package com.ruicar.afs.cloud.afscase.processor.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.approvetask.entity.*;
import com.ruicar.afs.cloud.afscase.approvetask.service.CaseApproveRecordService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolHistoryService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.common.utils.Const;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.*;
import com.ruicar.afs.cloud.afscase.infomanagement.service.*;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.service.ApproveInformInfoService;
import com.ruicar.afs.cloud.afscase.processor.enums.NormalSubmitType;
import com.ruicar.afs.cloud.afscase.processor.service.ChangeAssetsWorkflowService;
import com.ruicar.afs.cloud.afscase.processor.util.WorkflowTypeUtil;
import com.ruicar.afs.cloud.afscase.processor.vo.NormalBusinessDataVO;
import com.ruicar.afs.cloud.afscase.processor.vo.NormalTaskSubmitVO;
import com.ruicar.afs.cloud.afscase.reconsiderationprocess.entity.ApproveReconsiderationInfo;
import com.ruicar.afs.cloud.afscase.reconsiderationprocess.service.ReconsiderationProcessService;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinDiscountDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinFinancingItems;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinRentAdjustDetails;
import com.ruicar.afs.cloud.common.core.enums.AfsBaseEnum;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.seats.entity.UserCollocation;
import com.ruicar.afs.cloud.seats.service.UserCollocationService;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.WorkFlowResponse;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.FLowGiveUpRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.QueryFLowCmdRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.StartFlowRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.TaskSubmitRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.response.FlowCmdBean;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @description: 流程发起
 * @author jiaqi.guo
 * @created 2020/7/27 19:18
 * @version 1.0
 */
@Service
@Slf4j
@AllArgsConstructor
public class ChangeAssetsWorkflowServiceImpl implements ChangeAssetsWorkflowService {

    private WorkflowService workflowService;
    private CaseBaseInfoService caseBaseInfoService;
    private WorkProcessScheduleInfoService workProcessScheduleInfoService;
    private CaseApproveRecordService caseApproveRecordService;
    private WorkTaskPoolService workTaskPoolService;
    private ApproveInformInfoService approveInformInfoService;
    private WorkTaskPoolHistoryService workTaskPoolHistoryService;
    private CaseCostInfoService caseCostInfoService;
    private CaseChannelInfoService caseChannelInfoService;
    private CaseCarInfoService caseCarInfoService;
    private CaseCarStyleDetailService caseCarStyleDetailService;
    private UserCollocationService userCollocationService;
    private ApproveAssetsChangeService approveAssetsChangeService;
    private CaseCustInfoService custInfoService;
    private CaseFinancingItemsService financingItemsService;
    private CaseFinRentAdjustDetailsService   rentAdjustDetailsService;
    private CaseDiscountDetailService    caseDiscountDetailService;
    private ReconsiderationProcessService reconsiderationProcessService;
    private CaseRedundantInfoService redundantInfoService;
    /**
     * @description: 流程发起
     * @author jiaqi.guo
     * @created 2020/7/27 19:18
     * @version 1.0
     */
    @Override
    public WorkFlowResponse start(WorkProcessScheduleInfoTemp temp) {
        StartFlowRequest request = new StartFlowRequest();
        request.setAfsFlowKey(temp.getAfsFlowKey());
        request.setBizDataId(Convert.toStr(temp.getId()));
        request.setFlowName(new StringBuffer(temp.getApplyNo())
                .append("-")
                .append(WorkflowTypeUtil.getApproveTypeName(temp.getAfsFlowKey()))
                .append("(")
                .append(WorkflowTypeUtil.getType(temp.getAfsFlowKey()).getDesc())
                .append(")").toString());
        log.info("流程发起 ==> {}", request);
        WorkFlowResponse response = workflowService.startWorkFlow(request, getBusinessData(temp.getApplyNo()));
        if (Const.WORKFLOW_RESPONSE_SUCCESS == response.getSuccess()) {
            saveStartRecord(temp, caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>lambdaQuery().eq(CaseBaseInfo::getApplyNo, temp.getApplyNo())));
        } else {
            throw new AfsBaseException(response.getCode(), response.getMessage());
        }
        return response;
    }

    /**
     * @description: 流程提交
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(NormalTaskSubmitVO submitVO) {
        if (Objects.isNull(submitVO.getWorkFlowInfo())) {
            submitVO.setWorkFlowInfo(workProcessScheduleInfoService.getById(submitVO.getRecord().getStageId()));
        }
        if (Objects.isNull(submitVO.getWorkTaskPool())) {
            submitVO.setWorkTaskPool(workTaskPoolService.getOne(
                    Wrappers.<WorkTaskPool>lambdaQuery()
                            .eq(WorkTaskPool::getStageId, submitVO.getRecord().getStageId())
                            .eq(WorkTaskPool::getTaskNodeId, submitVO.getWorkFlowInfo().getCurrentNodeId())
                            .eq(WorkTaskPool::getApproveStaff, SecurityUtils.getUser().getUsername())));
        }
        NormalSubmitType submitEnum = (NormalSubmitType) AfsEnumUtil.getEnum(submitVO.getRecord().getApproveSuggest(), NormalSubmitType.class);
        switch (submitEnum) {
            case SUGGEST_CHECK:
                check(submitVO);
                break;
            case SUGGEST_REJECT:
                reject(submitVO);
                break;
            case SUGGEST_CANCEL:
                cancel(submitVO);
                break;
            case SUGGEST_REJECT_FINAL:
                checkApproveAmountLimit(submitVO.getWorkFlowInfo().getApplyNo());
                rejectFinal(submitVO);
                break;
            case SUGGEST_CHECK_FINAL:
                checkApproveAmountLimit(submitVO.getWorkFlowInfo().getApplyNo());
                updateChangeAssets(submitVO.getWorkFlowInfo().getApplyNo());
                checkFinal(submitVO);
                break;
            case SEND_BACK:
                sendBack(submitVO);
                break;
            case SEND_BACK_TO_DEALER:
                //add by yk.Li 20200625
                sendBackToDealer(submitVO);
                break;
            case PARSE:
                parse(submitVO);
                break;
            case MODIFY_SUBMIT:
                dealerSubmit(submitVO);
                break;
            default:
                log.info("审批建议不存在:{}", submitEnum);
        }
    }
    @Transactional(rollbackFor = Exception.class)
    public void parse(NormalTaskSubmitVO submitVO) {
        // 更改案件状态
        CaseApproveRecord record = submitVO.getRecord();
        caseBaseInfoService.update(
                Wrappers.<CaseBaseInfo>lambdaUpdate()
                        .eq(CaseBaseInfo::getApplyNo, record.getApplyNo())
                        .set(CaseBaseInfo::getBusinessStateIn, AfsEnumUtil.key(BusinessStateInEnum.PAUSE))
        );
        caseApproveRecordService.save(record);
    }

    /**
     * 经销商提交
     * @param submitVO
     */
    private void dealerSubmit(NormalTaskSubmitVO submitVO) {
        approveAssetsChangeService.update(
                Wrappers.<ApproveAssetsChangeInfo>lambdaUpdate()
                        .eq(ApproveAssetsChangeInfo::getApplyNo, submitVO.getWorkFlowInfo().getApplyNo())
                        .set(ApproveAssetsChangeInfo::getStatus, AfsEnumUtil.key(BusinessStateInEnum.REVISE_REPLY))
        );
        workTaskPoolService.removeById(submitVO.getWorkTaskPool().getId());
        caseApproveRecordService.save(submitVO.getRecord());
        WorkFlowResponse resp = pushWorkflow(NormalSubmitType.MODIFY_SUBMIT, submitVO);
        if (Const.WORKFLOW_RESPONSE_SUCCESS != resp.getSuccess()) {
            throw new AfsBaseException(resp.getCode(), resp.getMessage());
        }
    }

    /**
     * @description:保存流程发起日志
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveStartRecord(WorkProcessScheduleInfoTemp infoTemp, CaseBaseInfo caseInfo) {
        CaseApproveRecord record = new CaseApproveRecord();
        record.setStageId(Convert.toStr(infoTemp.getId()));
        record.setApplyNo(infoTemp.getApplyNo());
        record.setApproveSuggestName("资产变更发起流程");
        record.setApproveType(ApproveTypeEnum.PROCESS.getValue());
        record.setApproveStartTime(infoTemp.getStartTime());
        record.setApproveEndTime(infoTemp.getStartTime());
        record.setDisposeStaff("系统");
        record.setDisposeNodeName("开始节点");
        caseApproveRecordService.save(record);

        //资产变更申请表
        saveChangeAssetsInfo(infoTemp);


        // 通知进件端
        CaseApproveRecord noticeRecord = new CaseApproveRecord();
        noticeRecord.setApplyNo(record.getApplyNo());
        noticeRecord.setApproveStartTime(new Date());
        noticeRecord.setApproveSuggest(SendApproveTypeEnum.PENDING_REVIEW.getCode());
        approveInformInfoService.submitApprovalNoticForAssets(noticeRecord);
    }

    /**
     * @description:建议核准
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    public void check(NormalTaskSubmitVO submitVO) {
        changeCaseStatusAndSaveRecord(BusinessStateInEnum.ADVICE_APPROVED, submitVO);
        WorkFlowResponse resp = pushWorkflow(NormalSubmitType.SUGGEST_CHECK, submitVO);
        afterSubmit(resp);
    }

    /**
     * @description: 建议拒绝
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    public void reject(NormalTaskSubmitVO submitVO) {
        changeCaseStatusAndSaveRecord(BusinessStateInEnum.ADVICE_REJECT, submitVO);
        WorkFlowResponse resp = pushWorkflow(NormalSubmitType.SUGGEST_REJECT, submitVO);
        afterSubmit(resp);
    }


    /**
     * @description: 撤销
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    public void cancel(NormalTaskSubmitVO submitVO) {
        changeCaseStatusAndSaveRecord(BusinessStateInEnum.REPEAL, submitVO);

        // 撤销提交
        FLowGiveUpRequest giveUpRequest = new FLowGiveUpRequest();
        giveUpRequest.setFlowInstanceId(submitVO.getWorkFlowInfo().getStageId());
        giveUpRequest.setReason(submitVO.getRecord().getApproveRemark());
        workflowService.flowGiveUp(giveUpRequest);
        callApplySystem(submitVO.getRecord());
    }

    /**
     * @Description 拒绝
     * @Author guojiaqi
     * @Date 2020/6/16 13:54
     */
    public void rejectFinal(NormalTaskSubmitVO submitVO) {
        changeCaseStatusAndSaveRecord(BusinessStateInEnum.REJECT, submitVO);
        WorkFlowResponse resp = pushWorkflow(NormalSubmitType.SUGGEST_REJECT_FINAL, submitVO);
        afterSubmit(resp);
        callApplySystem(submitVO.getRecord());
    }

    /**
     * @description: 核准
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    public void checkFinal(NormalTaskSubmitVO submitVO) {
        changeCaseStatusAndSaveRecord(BusinessStateInEnum.APPROVED, submitVO);
        WorkFlowResponse resp = pushWorkflow(NormalSubmitType.SUGGEST_CHECK_FINAL, submitVO);
        afterSubmit(resp);
        callApplySystem(submitVO.getRecord());
    }

    /**
     * @description: 资产变更同通知
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    public void callApplySystem(CaseApproveRecord record) {
        if(UseSceneEnum.CHANGE_ASSETS.getValue().equals(record.getUseScene())){
            approveInformInfoService.approveChangeAssets(record);
        }
        if(UseSceneEnum.RECONSIDER.getValue().equals(record.getUseScene())&&!record.getApproveSuggest().equals(AfsEnumUtil.key(NormalSubmitType.SUGGEST_CHECK))){
            approveInformInfoService.approveReconsideration(record);
        }

    }

    @Override
    @Transactional
    public WorkFlowResponse cancelFlow(String stageId,String message) {
        log.info("流程撤销 ==> 操作人：{},流程编号：{}",SecurityUtils.getUsername(),stageId);
        WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(stageId);
        List<WorkTaskPool> poolList = workTaskPoolService.list(
                Wrappers.<WorkTaskPool>lambdaQuery().eq(WorkTaskPool::getStageId,stageId)
        );
        CaseApproveRecord record = new CaseApproveRecord();
        record.setStageId(Convert.toStr(info.getId()));
        record.setUseScene(UseSceneEnum.CHANGE_ASSETS.getValue());
        record.setDisposeStaff(SecurityUtils.getUser().getUserRealName());
        record.setApproveType(ApproveTypeEnum.PROCESS.getValue());
        record.setDisposeNode(info.getCurrentNodeId());
        record.setDisposeNodeName(info.getCurrentNodeName());
        record.setApproveStartTime(poolList.get(0).getStartTime());
        record.setApproveEndTime(new Date());
        record.setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.SUGGEST_CANCEL));
        record.setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.SUGGEST_CANCEL));
        record.setApplyNo(info.getApplyNo());
        record.setApproveRemark(message);
        // 保存操作日志
        caseApproveRecordService.save(record);
        // 删除已存在的待办任务
        workTaskPoolService.removeByIds(poolList.stream().map(pool -> Convert.toStr(pool.getId())).collect(Collectors.toList()));


        // 调用工作流引擎接口，改派
        FLowGiveUpRequest giveUpRequest = new FLowGiveUpRequest();
        giveUpRequest.setReason(message);
        giveUpRequest.setFlowInstanceId(info.getStageId());
        WorkFlowResponse response = workflowService.flowGiveUp(giveUpRequest);
        if(Const.WORKFLOW_RESPONSE_SUCCESS != response.getSuccess()){
            throw new AfsBaseException(response.getCode(),response.getMessage());
        }
        /**更改资产变更主表状态*/

        // 通知进件系统
        callApplySystem(record);
        return response;
    }

    /**
     * @description: 提交，工作流推进
     * @author jiaqi.guo
     * @created 2020/7/27 19:20
     * @version 1.0
     */
    public WorkFlowResponse pushWorkflow(Enum<? extends AfsBaseEnum> submitButtonEnum, NormalTaskSubmitVO submitVO) {
        WorkTaskPool taskPool = submitVO.getWorkTaskPool();
        String cmdName = AfsEnumUtil.desc(submitButtonEnum);
        QueryFLowCmdRequest cmdQueryRequest = new QueryFLowCmdRequest();
        cmdQueryRequest.setFlowInstanceId(submitVO.getWorkFlowInfo().getStageId());
        WorkFlowResponse<List<FlowCmdBean>> flowCmdResp = workflowService.queryFlowCmd(cmdQueryRequest);
        Assert.isTrue(Const.WORKFLOW_RESPONSE_SUCCESS == flowCmdResp.getSuccess(),flowCmdResp.getMessage());
        Assert.isTrue(CollectionUtil.isNotEmpty(flowCmdResp.getAfsData()),"未获取到当前节点可操作命令");
        TaskSubmitRequest submitRequest = new TaskSubmitRequest();
        List<FlowCmdBean> cmdBeanList = flowCmdResp.getAfsData();
        for (FlowCmdBean flowCmdBean : cmdBeanList) {
            if(StrUtil.equals(flowCmdBean.getCmdDis(),cmdName)){
                submitRequest.setAfsFlowKey(submitVO.getWorkFlowInfo().getAfsFlowKey());
                submitRequest.setCmdId(flowCmdBean.getId());
                submitRequest.setBizDataId(Convert.toStr(taskPool.getStageId()));
                submitRequest.setGwtUserId(taskPool.getWorkflowDisposeId());
                break;
            }
        }
        Assert.isTrue(StrUtil.isNotBlank(submitRequest.getGwtUserId()),"当前节点未知的提交命令："+cmdName);
        return workflowService.taskSubmit(submitRequest,getBusinessData(submitVO.getRecord().getApplyNo()));
    }
    /**
     * @description: 提交成功修改数据
     * @author jiaqi.guo
     * @created 2020/7/27 19:20
     * @version 1.0
     */
    public void afterSubmit(WorkFlowResponse resp){
        if(Const.WORKFLOW_RESPONSE_SUCCESS != resp.getSuccess()) {
            throw new AfsBaseException(resp.getCode(),resp.getMessage());
        }
    }
    /**
     * @description: 保存日志
     * @author jiaqi.guo
     * @created 2020/7/27 19:20
     * @version 1.0
     */
    @Transactional(rollbackFor = Exception.class)
    public void changeCaseStatusAndSaveRecord(BusinessStateInEnum stateInEnum, NormalTaskSubmitVO submitVO) {
        CaseApproveRecord record = submitVO.getRecord();
        // 删除当前任务，存入历史任务表
        WorkTaskPool taskPool = submitVO.getWorkTaskPool();
        // 更资产变更、复议状态
        if(ProcessTypeEnum.CHANGE_ASSETS.getCode().equals(taskPool.getProcessType())){
            if (!stateInEnum.equals(BusinessStateInEnum.NONE)) {
                approveAssetsChangeService.update(
                        Wrappers.<ApproveAssetsChangeInfo>lambdaUpdate()
                                .eq(ApproveAssetsChangeInfo::getApplyNo, record.getApplyNo())
                                .eq(ApproveAssetsChangeInfo::getStageId,record.getStageId())
                                .set(ApproveAssetsChangeInfo::getStatus, AfsEnumUtil.key(stateInEnum))
                );
            }
        }
        else if(ProcessTypeEnum.RECONSIDER_APPLY.getCode().equals(taskPool.getProcessType())){
            if (!stateInEnum.equals(BusinessStateInEnum.NONE)) {
                reconsiderationProcessService.update(
                        Wrappers.<ApproveReconsiderationInfo>lambdaUpdate()
                                .eq(ApproveReconsiderationInfo::getApplyNo, record.getApplyNo())
                                .eq(ApproveReconsiderationInfo::getStageId,record.getStageId())
                                .set(ApproveReconsiderationInfo::getStatus, AfsEnumUtil.key(stateInEnum))
                );
            }
        }


        AfsUser user = SecurityUtils.getUser();
        List<WorkTaskPool> currentNodeTask = workTaskPoolService.list(
                Wrappers.<WorkTaskPool>lambdaQuery().eq(WorkTaskPool::getStageId,taskPool.getStageId())
                        .eq(WorkTaskPool::getTaskNodeId,taskPool.getTaskNodeId())
        );
        taskPool.setEndTime(new Date());
        record.setDisposeStaff(SecurityUtils.getUser().getUserRealName());
        record.setDisposeNode(taskPool.getTaskNodeId());
        record.setDisposeNodeName(taskPool.getTaskNodeName());
        record.setApproveStartTime(taskPool.getStartTime());
        record.setApproveEndTime(taskPool.getEndTime());
        // 保存审批建议数据，暂存
        JSONObject remain = new JSONObject();
        if (StrUtil.isNotBlank(taskPool.getRemainData())) {
            remain = JSONObject.parseObject(taskPool.getRemainData());
        }
        remain.put(AfsEnumUtil.key(RemainKeyEnum.RECORD), JSONObject.toJSON(record));
        taskPool.setRemainData(remain.toString());
        WorkTaskPoolHistory taskPoolHistory = workTaskPoolHistoryService.getOne(
                Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                        .eq(WorkTaskPoolHistory::getStageId, record.getStageId())
                        .eq(WorkTaskPoolHistory::getTaskNodeId,submitVO.getWorkTaskPool().getTaskNodeId())
                        .eq(WorkTaskPoolHistory::getApproveStaff, user.getUsername())
        );
        if (Objects.nonNull(taskPoolHistory)) {
            workTaskPoolHistoryService.removeById(taskPoolHistory);
        }
        WorkTaskPoolHistory currentPoolHistory = new WorkTaskPoolHistory();
        String[] ignoreFieldNames = new String[]{"id", "createBy", "createTime", "delFlag"};
        BeanUtil.copyProperties(taskPool, currentPoolHistory, ignoreFieldNames);
        List<Long> ids = new ArrayList<>(currentNodeTask.size());
        currentNodeTask.forEach( task -> ids.add(task.getId()));
        workTaskPoolService.removeByIds(ids);
        workTaskPoolHistoryService.save(currentPoolHistory);

        // 保存流程操作日志
        caseApproveRecordService.save(record);
    }
    /**
     * @description: 退回
     * @author jiaqi.guo
     * @created 2020/7/27 19:21
     * @version 1.0
     */
    public void sendBack(NormalTaskSubmitVO submitVO) {
        if(WhetherEnum.YES.getCode().equals(submitVO.getWorkFlowInfo().getFirstTrail())){
            sendBackToDealer(submitVO);
        }else {
            changeCaseStatusAndSaveRecord(BusinessStateInEnum.NONE,submitVO);
            WorkFlowResponse resp = pushWorkflow(NormalSubmitType.SEND_BACK,submitVO);
            afterSubmit(resp);
        }
    }

    /**
     * @description: 退回至经销商
     * @author jiaqi.guo
     * @created 2020/7/27 19:21
     * @version 1.0
     */
    public void sendBackToDealer(NormalTaskSubmitVO submitVO){
        submitVO.getRecord().setApproveSuggestName(AfsEnumUtil.desc(NormalSubmitType.SEND_BACK_TO_DEALER));
        changeCaseStatusAndSaveRecord(BusinessStateInEnum.REVISE_PARSE,submitVO);
        submitVO.getRecord().setApproveSuggest(AfsEnumUtil.key(NormalSubmitType.SEND_BACK_TO_DEALER));
        WorkFlowResponse resp = pushWorkflow(NormalSubmitType.SEND_BACK_TO_DEALER,submitVO);
        afterSubmit(resp);
        approveInformInfoService.submitApprovalNoticForAssets(submitVO.getRecord());
    }
    /**
     * @description: 业务数据获取
     * @author jiaqi.guo
     * @created 2020/7/27 19:21
     * @version 1.0
     */
    public JSONObject getBusinessData(String applyNo){
        // 基本信息
        CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(
                Wrappers.<CaseBaseInfo>lambdaQuery().eq(CaseBaseInfo::getApplyNo, applyNo)
        );
        // 车款费用信息
        FinCostDetails FinCostDetailsCar = caseCostInfoService.getOne(
                Wrappers.<FinCostDetails>lambdaQuery().eq(FinCostDetails::getApplyNo, applyNo)
                        .eq(FinCostDetails::getCostType, CostTypeEnum.CARAMT.getCode())
        );
        FinCostDetailsCar = Objects.nonNull(FinCostDetailsCar) ? FinCostDetailsCar : new FinCostDetails();
        // 附加贷费用信息
        FinCostDetails FinCostDetailsAppend = caseCostInfoService.getOne(
                Wrappers.<FinCostDetails>lambdaQuery().eq(FinCostDetails::getApplyNo, applyNo)
                        .eq(FinCostDetails::getCostType, CostTypeEnum.AFFIXAMT.getCode())
        );
        FinCostDetailsAppend = Objects.nonNull(FinCostDetailsAppend) ? FinCostDetailsAppend : new FinCostDetails();
        // 渠道信息
        CaseChannelInfo channelInfo = caseChannelInfoService.getOne(
                Wrappers.<CaseChannelInfo>lambdaQuery().eq(CaseChannelInfo::getApplyNo, applyNo)
        );
        channelInfo = Objects.nonNull(channelInfo) ? channelInfo : new CaseChannelInfo();
        // 车辆信息
        CaseCarInfo caseCarInfo = caseCarInfoService.getOne(
                Wrappers.<CaseCarInfo>lambdaQuery().eq(CaseCarInfo::getApplyNo, applyNo)
        );
        caseCarInfo = Objects.nonNull(caseCarInfo) ? caseCarInfo : new CaseCarInfo();
        // 车辆详情信息
        CaseCarStyleDetail carStyleDetailInfo = caseCarStyleDetailService.getOne(
                Wrappers.<CaseCarStyleDetail>lambdaQuery().eq(CaseCarStyleDetail::getCarId, caseCarInfo.getId())
        );
        carStyleDetailInfo = Objects.nonNull(carStyleDetailInfo) ? carStyleDetailInfo : new CaseCarStyleDetail();
        // TODO 取值待调整
        NormalBusinessDataVO businessDataVO = NormalBusinessDataVO.builder()
                .loanAmountAddUp(BigDecimal.ZERO)
                .businessType(caseBaseInfo.getBusinessType())
                .decisionValue("")//决策引擎返回值
                .XuanWuGrade("")//玄武评分
                .dealerQualityGrade("")//经销商优质等级
                .turningMark("")
                .conditionMark("")
                .assigned("")//是否指定处理人
                .carType(Convert.toStr(caseBaseInfo.getCarType()))
                .carNature(Convert.toStr(caseBaseInfo.getCarNature()))
                .operateWay(Convert.toStr(caseBaseInfo.getOperateWay(), ""))
                .affiliatedWay(caseBaseInfo.getAffiliatedWay())
                .qualityGrade("")//优质等级
                .newEnergy(carStyleDetailInfo.getIsGreen())
                .channelBelong("")//渠道归属
                .appendLoanAmount(FinCostDetailsAppend.getLoanAmt())
                .carLevel(caseCarInfo.getCarBodyClass())
                .assetsClass(carStyleDetailInfo.getCarType())
                .carTypeDetail(carStyleDetailInfo.getCarTypeDetail())
                .dealerName(channelInfo.getDealerName())
                .antiFraudGrade("")//反欺诈评分
                .decisionGrade("")//决策引擎评分
                .loanAmount(FinCostDetailsCar.getLoanAmt())
                .carDownPayScale(FinCostDetailsCar.getDownPayScale())
                .carLoanAmount(FinCostDetailsCar.getLoanAmt())
                .carDiscountAmount(Convert.toBigDecimal(FinCostDetailsCar.getDiscountAmt()))
                .carFinalPayment(FinCostDetailsCar.getTailPayAmt())
                .carRepayType(null)
                .appendDownPayScale(FinCostDetailsAppend.getDownPayScale())
                .appendLoanAmount(FinCostDetailsAppend.getLoanAmt())
                .appendDiscountAmount(FinCostDetailsAppend.getDiscountAmt())
                .appendFinalPayment(FinCostDetailsAppend.getTailPayAmt())
                .remoteSign(caseBaseInfo.getAutomaticTag())
                .build();
        return JSONObject.parseObject(JSONObject.toJSONString(businessDataVO));
    }

    /**
     * @Description 校验当前操作员审批金额
     * @Author guojiaqi
     * @Date 2020/7/23 17:31
     */
    public void checkApproveAmountLimit(String applyNo) {
        CaseBaseInfo baseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>lambdaQuery().eq(CaseBaseInfo::getApplyNo, applyNo));
        UserCollocation user = userCollocationService.getOne(Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, SecurityUtils.getUsername()));
        if (baseInfo.getLoanAmtRepeat().compareTo(Convert.toBigDecimal(user.getApprovedAmount(), BigDecimal.ZERO)) == 1) {
            throw new AfsBaseException("操作失败，当前操作员审批金额权限不够");
        }
    }
    /**
     * @description: 资产变更申请表
     * @author jiaqi.guo
     * @created 2020/7/30 15:50
     * @version 1.0
     */
    private void  saveChangeAssetsInfo(WorkProcessScheduleInfoTemp temp){
        ApproveAssetsChangeInfo changeInfo=new ApproveAssetsChangeInfo();
        changeInfo.setApplyNo(temp.getApplyNo());
        changeInfo.setStageId(Convert.toStr(temp.getId()));
        changeInfo.setStatus(AfsEnumUtil.key(BusinessStateInEnum.WAIT_CHECK));
        CaseCustInfo caseCustInfo=custInfoService.getOne(Wrappers.<CaseCustInfo>query().lambda()
                .eq(CaseCustInfo::getApplyNo,temp.getApplyNo())
                .eq(CaseCustInfo::getCustRole,AfsEnumUtil.key(CustRoleEnum.MIANCUST)));
        changeInfo.setCustId(caseCustInfo.getId());
        approveAssetsChangeService.save(changeInfo);
    }
    /**
     * @Description 审核通过变更资产信息
     * @Author guojiaqi
     * @Date 2020/7/23 17:31
     */
    private void updateChangeAssets(String applyNo) {
        CaseRedundantInfo redundantInfo = redundantInfoService.getOne(Wrappers.<CaseRedundantInfo>lambdaQuery().eq(CaseRedundantInfo::getApplyNo, applyNo));
        String assetsRepeat=redundantInfo.getChangeAssetsRepeat();

        if(StringUtils.isNotBlank(assetsRepeat)){
            JSONObject jsonObject= JSONObject.parseObject(assetsRepeat);
            //变更实体
            JSONObject json=jsonObject.getJSONObject("bodyContent");
            //车辆信息
            JSONArray arrayCar=json.getJSONArray("finCarDetailsList");
            if(ObjectUtils.isNotEmpty(arrayCar)&&arrayCar.size()>0){
                /**  解析车辆信息CaseCarInfo*/
                caseCarInfoService.remove(Wrappers.<CaseCarInfo>query().lambda()
                        .eq(CaseCarInfo::getApplyNo,applyNo));
                ArrayList<CaseCarInfo> caseCarList = new ArrayList<>();
                for (CaseCarInfo caseCarInfo : arrayCar.toJavaList(CaseCarInfo.class)) {
                    CaseCarInfo carInfo = new CaseCarInfo();
                    BeanUtils.copyProperties(caseCarInfo, carInfo);
                    caseCarList.add(carInfo);
                }
                caseCarInfoService.saveBatch(caseCarList, caseCarList.size());
                log.info("资产变更车辆信息add成功！！！");
            }
            //车辆详情
            JSONArray arrayStyleDetail=json.getJSONArray("finCarStyleDetailList");
            if(ObjectUtils.isNotEmpty(arrayStyleDetail)&&arrayStyleDetail.size()>0){
                ArrayList<CaseCarStyleDetail> caseStyleDetailList = new ArrayList<>();
                for (CaseCarStyleDetail  carStyleDetail : arrayCar.toJavaList(CaseCarStyleDetail.class)) {
                    CaseCarStyleDetail styleDetail = new CaseCarStyleDetail();
                    BeanUtils.copyProperties(carStyleDetail, styleDetail);
                    caseStyleDetailList.add(styleDetail);
                }
                caseCarStyleDetailService.updateBatchById(caseStyleDetailList, caseStyleDetailList.size());
                log.info("资产变更车辆详情信息update成功！！！");
            }
            //融资项
            JSONArray arrayFinancing=json.getJSONArray("finFinancingItemsList");
            if(ObjectUtils.isNotEmpty(arrayFinancing)&&arrayFinancing.size()>0){
                /**  解析融资信息FinFinancingItems*/
                financingItemsService.deleteByApplyNo(applyNo);
                ArrayList<FinFinancingItems> financingItemsList = new ArrayList<>();
                for (FinFinancingItems financingItems : arrayFinancing.toJavaList(FinFinancingItems.class)) {
                    FinFinancingItems finFinancingItems = new FinFinancingItems();
                    BeanUtils.copyProperties(financingItems, finFinancingItems);
                    financingItemsList.add(finFinancingItems);
                }
                financingItemsService.saveBatch(financingItemsList, financingItemsList.size());
                log.info("资产变更融资项信息add成功！！！");
            }
            //租金调整
            JSONArray arrayRentAdjust=json.getJSONArray("finRentAdjustDetailsList");

            if(ObjectUtils.isNotEmpty(arrayRentAdjust)&&arrayRentAdjust.size()>0){
                /**  解析车辆信息CaseCarInfo*/
                rentAdjustDetailsService.deleteByApplyNo(applyNo);
                ArrayList<FinRentAdjustDetails> rentAdjustDetailsList = new ArrayList<>();
                for (FinRentAdjustDetails adjustDetails : arrayRentAdjust.toJavaList(FinRentAdjustDetails.class)) {
                    FinRentAdjustDetails rentAdjustDetails = new FinRentAdjustDetails();
                    BeanUtils.copyProperties(adjustDetails, rentAdjustDetails);
                    rentAdjustDetailsList.add(rentAdjustDetails);
                }

                rentAdjustDetailsService.saveBatch(rentAdjustDetailsList, rentAdjustDetailsList.size());
                log.info("资产变更车辆信息add成功！！！");
            }
            //融资信息
            JSONArray  costDetailsList=json.getJSONArray("finCostDetailsList");
            if(ObjectUtils.isNotEmpty(costDetailsList)&&costDetailsList.size()>0){
                /**  解析融资信息*/
                caseCostInfoService.deleteByApplyNo(applyNo);
                ArrayList<FinCostDetails> finCostDetailsList = new ArrayList<>();

                //更新主表贷款金额
                CaseBaseInfo caseBaseInfo = caseBaseInfoService.getOne(Wrappers.<CaseBaseInfo>query().lambda()
                        .eq(CaseBaseInfo::getApplyNo, applyNo));
                BigDecimal loanAmt=BigDecimal.ZERO;

                for (FinCostDetails finCostDetails : costDetailsList.toJavaList(FinCostDetails.class)) {
                    FinCostDetails costDetails = new FinCostDetails();
                    BeanUtils.copyProperties(finCostDetails, costDetails);
                    finCostDetailsList.add(costDetails);

                    loanAmt=loanAmt.add(finCostDetails.getLoanAmt());
                    if (CostTypeEnum.CARAMT.getCode().equals(finCostDetails.getCostType())) {
                        caseBaseInfo.setDownPayScaleRepeat(finCostDetails.getDownPayScale());
                        caseBaseInfo.setLoanTermsRepeat(finCostDetails.getLoanTerm());
                    }
                }

                caseBaseInfo.setLoanAmtRepeat(loanAmt);
                caseBaseInfoService.updateById(caseBaseInfo);
                caseCostInfoService.saveBatch(finCostDetailsList, finCostDetailsList.size());
                log.info("资产变更融资信息add成功！！！");
            }
            //贴息明细
            JSONArray discountList=json.getJSONArray("finDiscountDetailsList");
            if(ObjectUtils.isNotEmpty(discountList)&&discountList.size()>0){
                /**  解析贴息明细*/
                caseDiscountDetailService.deleteByApplyNo(applyNo);
                ArrayList<FinDiscountDetails> finDiscountDetailsList = new ArrayList<>();
                for (FinDiscountDetails discountDetails : discountList.toJavaList(FinDiscountDetails.class)) {
                    FinDiscountDetails costDetails = new FinDiscountDetails();
                    BeanUtils.copyProperties(discountDetails, costDetails);
                    finDiscountDetailsList.add(costDetails);
                }
                caseDiscountDetailService.saveBatch(finDiscountDetailsList, finDiscountDetailsList.size());
                log.info("资产变更贴息明细add成功！！！");
            }


        }else{
            throw  new AfsBaseException("不存在可变更资产数据!!!");
        }

    }
}